package birdsong.dummy.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.concurrent.LinkedBlockingQueue;

import org.junit.Test;

import birdsong.comm.ClientSideMessage.Type;
import birdsong.comm.ServerSideMessage;
import birdsong.dummy.ClientCommDummy;
import birdsong.dummy.ServerCommDummy;

public class ServerCommDummyTest {
    private ServerCommDummy serverCommDummy;

    @Test
    public void testStart() {
	ServerThread serverThread = new ServerThread();
	serverThread.start();

	ClientCommDummy Dori = new ClientCommDummy();
	Dori.connect("localhost", "Dori");

	LinkedBlockingQueue<ServerSideMessage> listaMensagensServer = serverCommDummy.getMensagensServidor();
	assertTrue(listaMensagensServer.isEmpty());
	serverThread.setServerRunning(false);
    }

    @Test
    public void testHasNextMessage() {
	ServerThread serverThread = new ServerThread();
	serverThread.start();

	ClientCommDummy Dori = new ClientCommDummy();
	Dori.connect("localhost", "Dori");

	assertTrue(serverCommDummy.hasNextMessage());

	serverThread.setServerRunning(false);
    }

    @Test
    public void testGetNextMessage() {
	ServerThread serverThread = new ServerThread();
	serverThread.start();

	ClientCommDummy Dori = new ClientCommDummy();

	Dori.connect("localhost", "Dori");
	assertNotNull(serverCommDummy.getNextMessage());

	Dori.disconnect();
	serverThread.setServerRunning(false);
    }

    @Test
    public void testSendNewFollower() {
	ServerThread serverThread = new ServerThread();
	serverThread.start();

	ClientCommDummy Dori = new ClientCommDummy();
	ClientCommDummy Nemo = new ClientCommDummy();

	Dori.connect("localhost", "Dori");
	Nemo.connect("localhost", "Nemo");

	Nemo.follow("Dori");
	assertEquals(serverCommDummy.getNextMessage().getType(), Type.FOLLOWER);

	disconnectSystem(serverThread, Dori, Nemo);
    }

    private void disconnectSystem(ServerThread serverThread, ClientCommDummy Dori, ClientCommDummy Nemo) {
	Nemo.disconnect();
	Dori.disconnect();
	serverThread.setServerRunning(false);
    }

    @Test
    public void testClientIsConnected() {
	ServerThread serverThread = new ServerThread();
	serverThread.start();

	ClientCommDummy Dori = new ClientCommDummy();
	Dori.connect("localhost", "Dori");

	assertTrue(serverCommDummy.clientIsConnected("Dori"));
	Dori.disconnect();
	serverThread.setServerRunning(false);
    }

    @Test
    public void testSendClientDisconnected() {
	ServerThread serverThread = new ServerThread();
	serverThread.start();

	ClientCommDummy Dori = new ClientCommDummy();
	Dori.connect("localhost", "Dori");
	Dori.disconnect();
	assertFalse(serverCommDummy.clientIsConnected("Dori"));

	serverThread.setServerRunning(false);
    }

    // ////////////////////////////////////////////////////////////////////

    public class ServerThread extends Thread {

	public ServerThread() {
	    serverCommDummy = new ServerCommDummy();
	}

	public void setServerRunning(boolean b) {
	    serverCommDummy.setServerRunning(b);
	}

	public void run() {
	    serverCommDummy.start();
	}
    }

}
